package org.summerframework.component.mybites.redis;

import org.summerframework.core.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author 石超
 * @ClassName: RedisCache
 * @Description: (使用第三方缓存服务器redis ， 处理二级缓存)
 * @date 2014年6月9日 下午1:37:46
 */
@Slf4j
public class RedisMybatisCache implements Cache {
    /**
     * The ReadWriteLock.
     */
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private RedisTemplate<String, Object> redisTemplate;
    private BoundHashOperations<String, String, Object> hashOperations;
    private String id;
    private String redisId;

    RedisMybatisCache(final String id, RedisTemplate<String, Object> redisTemplate) {
        if (id == null) {
            throw new IllegalArgumentException("必须传入ID");
        }

        this.id = id;
        this.redisTemplate = redisTemplate;
        this.redisId = LoggingRedisCache.getRedisId(id);
    }

    public RedisTemplate<String, Object> getRedisTemplate() {
        if (redisTemplate == null) {
            redisTemplate = (RedisTemplate<String, Object>) SpringContextUtil.getBean("redisTemplate", RedisTemplate.class);
        }
        return redisTemplate;
    }

    public BoundHashOperations<String, String, Object> getHashOperations() {
        if (hashOperations == null) {
            hashOperations = getRedisTemplate().boundHashOps(redisId);
        }
        return hashOperations;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public int getSize() {
        Long size = getHashOperations().size();
        return size != null ? size.intValue() : 0;
    }

    @Override
    public void putObject(Object key, Object value) {
        getHashOperations().put(key.toString(), value);
    }

    @Override
    public Object getObject(Object key) {
        return getHashOperations().get(key.toString());
    }

    @Override
    public Object removeObject(Object key) {
        Object value = getHashOperations().get(key.toString());
        getHashOperations().delete(key.toString());

        return value;
    }

    @Override
    public void clear() {
        getRedisTemplate().delete(redisId);
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }
}
